#pragma once
//***********************************************************************
//	File:		TileSystem.h
//	Author:		Ryan Simmons
//	Course:		SGP 1405
//	Purpose:	Handles all information regarding tiles, their collision,
//				rendering, and pathfinding
//***********************************************************************
//***********************************************************************
//	Purposfully left blank for all comments regarding this file 
//	
//	
//	
//***********************************************************************

#include "Layer.h"
class Entity;

class TileSystem
{
	struct Size
	{
		int m_nWidth, m_nHeight;
	};
	
	struct TileSet
	{
		Size			m_szSize;
		SGD::HTexture	m_hImage;
	};

	struct EnemyShell
	{
		SGD::Point	m_ptLoc;
		int			m_nType;
	};

	struct SpawnGroup
	{
		DynArray<EnemyShell>	m_eEnemies;
		bool					m_bHasSpawned = false;
	};

public:
	/**********************************************************/
	// Singleton Accessor
	static TileSystem* GetInstance( void );

	/**********************************************************/
	// TileSystem Interface:
	void							Render				( void ) const;											// Render's the level
	bool							LoadLevel			( const char * path );									// Send XML filepath to load the level
	void							UnloadLevel			( void );												// Get rid of all the assets for the level
	SGD::Rectangle					CheckWorld			( const SGD::Rectangle object );						// Used to check entity movement against the world before moves are made
	SGD::Vector						GetPath				( Entity * ent, SGD::Point destination);				// Find the direction for a clear spot to move
	void							TriggerGroupSpawn	( unsigned int group );									// Tells the game to spawn all the enemies in the appropriate group if it has not been spawned
	
	/**********************************************************/
	// Accessors
	TileSet							GetTileSet			( unsigned int setID ) const;							// Returns the tileset based on input value
	SGD::Rectangle					GetSection			( unsigned int tileID, unsigned int setID) const;		// Returns the section of the tileset to draw
	Size							GetMapSize			( void ) const;											// Returns the map size in tiles
	Size							GetTileSize			( void ) const;											// Returns the size of in pixels of one tile
	DynArray<Layer>					GetLayers			( void ) const;											// Returns the vectors of layers
	SGD::Point						GetPlayerSpawn		( void ) const;											// Returns the players starting location
	SGD::Point						GetRenderPoint		( SGD::Point ) const;
	
private:
	/**********************************************************/
	// Singleton
	TileSystem				( void )					= default;
	~TileSystem				( void )					= default;

	TileSystem				( const TileSystem& )		= delete;
	TileSystem& operator=	( const TileSystem& )		= delete;

	/**********************************************************/
	// Variables
	bool							m_bLoaded = false;
	DynArray<Layer>					m_vLayers;																	// Vector of layers
	DynArray<SpawnGroup>			m_sgGroups;																	// Groups of enemies to spawn
	Size							m_szMapWH;																	// Map width and height
	Size							m_szTileWH;																	// Tile width and height
	SGD::Point						m_ptPlayerSpawn;															// Players Spawn location

	/**********************************************************/
	// Assets
	DynArray<TileSet>				m_vTileSets;																// Vector of tilesets for the current map

	/**********************************************************/
	// Macros
#define TILESYSTEM TileSystem::GetInstance()
#define LAYERS TILESYSTEM->GetLayers()
};

